package com.sdk.auth.aop;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.sdk.auth.entity.BaseResult;
import com.sdk.auth.enums.AuthErrorResultCode;
import com.sdk.auth.enums.ServerUrlEnum;
import com.sdk.auth.utils.AESUtil;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


/**
 * 返回值处理
 */
@Slf4j
@Aspect
@Order(2)
public class AESResultHandleAspect {

    @Resource
    private SensitiveKeyProperties sensitiveKeyProperties;

    @PostConstruct
    public void init() {
        log.info("初始化 AESResultHandleAspect: {}", this.getClass().getName());
    }

    @AfterReturning(pointcut = "(execution(* com.test1.modules..*.*(..)) " +
            "|| execution(* com.test2.modules..*.*(..)) " +
            "|| execution(* com.test3.modules..*.*(..)) " +
            ") && @annotation(org.springframework.web.bind.annotation.PostMapping)", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {
        if (null == joinPoint || null == result) {
            return;
        }
        /**
         * data不为空的时候才替换
         * 限定只有返回BaseResult的才做处理，其它类型不做处理
         */
        if(result instanceof BaseResult){
            BaseResult baseResult = (BaseResult)result;
            if(baseResult.getData() == null){
                return;
            }
            //防止重复加密，feign不能写在与controller同个包下
            if(baseResult.getAesKey() != null){
                return;
            }
            try {
                //请求地址判断，拦截固定开头的地址
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
                HttpServletRequest request = attributes.getRequest();
                if(!ServerUrlEnum.check(request.getRequestURI())){
                    return;
                }
                String aesKey = AESUtil.generateRandomKey();
                RSA rsa = sensitiveKeyProperties.getRsa();
                log.debug("请求地址:{},返回结果：{}", request.getRequestURI(),baseResult.getData());
                baseResult.setData(AESUtil.encrypt(baseResult.getData(), aesKey));
                baseResult.setAesKey(rsa.encryptBase64(aesKey, KeyType.PublicKey));
                log.debug("请求地址:{},返回结果加密后：{}", request.getRequestURI(),baseResult.getData());
            } catch (Exception e) {
                log.error("AESResultHandleAspect加密结果异常：{}", result, e);
                baseResult.setCode(AuthErrorResultCode.COMM_ERROR.getCode());
                baseResult.setMsg("结果加密失败");
                baseResult.setData(null);
            }
        }
    }
}
